using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using svs.Mobile.BeyondMedia.Controls;
using svs.Mobile.BeyondMedia.FeedCore;
using svs.Mobile.BeyondMedia.GraphicsAPI;
using svs.Mobile.BeyondMedia.Properties;
using svs.Mobile.BeyondMedia.UiCore;

namespace svs.Mobile.BeyondMedia.Forms.Settings
{
	/// <summary>
	/// Provide a 2 line listview
	/// </summary>
	internal class SettingsListView : OwnerDrawnList<Settings.SettingPage>
	{
		#region Delegates

		public delegate void PageSelectedEvent(Settings.SettingPage page);

		#endregion

		private const int FONT_SIZE = 9;
		private Color HighlightColor = SystemColors.InactiveCaption;
		private List<Settings.SettingPage> m_PageList = new List<Settings.SettingPage>();
		private int BorderWidth;

		public SettingsListView()
		{
			// We need a total of 5 rows, so the height is 180/5=36
			Graphics g = CreateGraphics();
			Font font = new Font(Font.Name, FONT_SIZE, FontStyle.Bold);
			// Calc line height to be height of letter A plus 10%
			ItemHeight = (int) (g.MeasureString("A", font).Height* (PlatformDetection.IsPocketPC()?2.3:1.5));
			g.Dispose();
			BorderWidth = PlatformDetection.IsPocketPC() ? 2 : 1;
			font.Dispose();
		}

		public Settings.SettingPage SelectedPage
		{
			get
			{
				if (SelectedIndex != -1 && m_PageList.Count > 0)
					return m_PageList[SelectedIndex];

				return new Settings.SettingPage(null,SettingsPageHolderForm.SettingsPages.General);
			}
			set
			{
				int i = m_PageList.IndexOf(value);

				if (SelectedIndex != i)
				{
					SelectedIndex = i;
				}

				EnsureVisible(SelectedIndex);
			}
		}

		public event PageSelectedEvent PageSelected;

		public void SetPages(List<Settings.SettingPage> value)
		{
			Clear();
			m_PageList.AddRange(value);
			Items.AddRange(value);
			SelectedIndex = 0;
			OnResize(null);
		}

		/// <summary>
		/// Custom OnPaint. This paints the listview items
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPaint(PaintEventArgs e)
		{
			// Get graphics object from bitmap.
			using (Graphics gOffScreen = PrepareOffscreenGraphics())
			{
				// Set the y pos of the current item
				int itemTop = 0;

				// Draw the visible items.
				for (int n = VScrollBar.Value; n <= VScrollBar.Value + DrawCount; n++)
				{
					Rectangle itemArea = new Rectangle(0,
					                                   itemTop,
					                                   ClientSize.Width - (VScrollBar.Visible ? VScrollBar.Width : 0),
					                                   ItemHeight);

					if (Items.Count == 0 || n < 0 || n > Items.Count - 1)
						break;

					itemArea.Inflate(-4, -3);

					// Get the current MailItem
					Settings.SettingPage page = Items[n];

					DrawItemBox(gOffScreen, n == SelectedIndex, itemArea);

					ImageAttributes ia = new ImageAttributes();
					ia.SetColorKey(Color.White, Color.White);

					Rectangle imgRect = new Rectangle(itemArea.Right - (Resources.MoreArrow.Width + 10), itemArea.Top + (itemArea.Height - Resources.MoreArrow.Height) / 2, Resources.MoreArrow.Width, Resources.MoreArrow.Height);
					gOffScreen.DrawImage(Resources.MoreArrow, imgRect, 0, 0, Resources.MoreArrow.Width, Resources.MoreArrow.Height, GraphicsUnit.Pixel, ia);
					
					using (Font font = new Font(Font.Name, FONT_SIZE, FontStyle.Regular))
					{
						Rectangle nameRect =
							new Rectangle(itemArea.Left + 10, itemArea.Top, itemArea.Width, itemArea.Height);

						StringFormat sf = new StringFormat();
						sf.Alignment = StringAlignment.Near;
						sf.LineAlignment = StringAlignment.Center;
						//Draw the track name
						using (Brush b = new SolidBrush(ForeColor))
						{
							gOffScreen.DrawString(page.PageName, font, b, nameRect, sf);
						}
					}

					// Set the next item top to move down the item height
					itemTop += ItemHeight;
				}

				// Now draw the visible list box
				e.Graphics.DrawImage(OffScreen, 0, 0);
			}
		}

		protected override Graphics PrepareOffscreenGraphics()
		{
			Graphics gOffScreen = Graphics.FromImage(OffScreen);
			gOffScreen.Clear(SystemColors.ScrollBar);
			return gOffScreen;
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Return:
					e.Handled = true;
					OnPageSelected();
					break;

				case Keys.Left:
					e.Handled = true;
					break;

				case Keys.Right:
					e.Handled = true;
					OnPageSelected();
					break;
			}

			if (!e.Handled)
			{
				base.OnKeyDown(e);
			}
		}

		protected override void OnKeyPress(KeyPressEventArgs e)
		{
			if (e.KeyChar == (Char) Keys.Escape)
			{
				e.Handled = true;
				OnCancel();
			}

			FindNextItemStartingWith(e.KeyChar);
		}

		private void OnCancel()
		{
			SelectedIndex = -1;
			OnPageSelected();
		}

		protected override void ItemClicked(int i_ItemIndex, int X, int Y, DragHelper.ClickSpeed speed)
		{
			base.ItemClicked(i_ItemIndex, X, Y, speed);

			if(speed == DragHelper.ClickSpeed.Fast)
					OnPageSelected();
		}

		private void OnPageSelected()
		{
			if (PageSelected != null)
			{
				PageSelected(SelectedPage);
			}
		}

		protected override void OnPaintBackground(PaintEventArgs e)
		{
			
		}

		/// <summary>
		/// Clears this instance.
		/// </summary>
		public void Clear()
		{
			SelectedIndex = -1;
			m_PageList.Clear();
			Items.Clear();
		}

		private void DrawItemBox(Graphics g, bool selected, Rectangle rc)
		{
			if (selected)
			{
				GraphicsHelper.DrawRoundedRectangle(g,
				                                    Color.WhiteSmoke,
				                                    BorderWidth,
				                                    HighlightColor,
				                                    rc,
				                                    new Size(8, 8));
			}
			else
			{
				GraphicsHelper.DrawRoundedRectangle(g,
				                                    Color.WhiteSmoke,
				                                    1,
				                                    Color.WhiteSmoke,
				                                    rc,
				                                    new Size(8, 8));
			}
		}
	}
}